

class MessageItem {

//    static let jsonDecoder = JSONDecoder()
    var model: OCTMessageAbstract? = nil
    
    var messageId: String = ""
    var conversationId: String = ""
    var userId: String = ""
    var isOutgoing: Bool = false
    var category: String = ""
    var content = ""
    var mediaUrl: String? = nil
    var mediaMimeType: String? = nil
    var mediaSize: Int64? = nil
    var mediaDuration: Int64? = nil
    var mediaWidth: Int? = nil
    var mediaHeight: Int? = nil
    var mediaHash: String? = nil
    var mediaKey: Data? = nil
    var mediaDigest: Data? = nil
    var mediaStatus: String? = nil
    var mediaWaveform: Data? = nil
    var thumbImage: String? = nil
    var status: String = ""
    var participantId: String? = nil
    var snapshotId: String? = nil
    var name: String? = nil
    var stickerId: String? = nil
    var createdAt: String = ""

    var actionName: String? = nil

    var userFullName: String = ""
    var userIdentityNumber: String = ""

    var appId: String? = nil

    var snapshotAmount: String? = nil
    var snapshotAssetId: String? = nil
    var snapshotType: String = ""

    var participantFullName: String? = nil
    var participantUserId: String? = nil

    var assetUrl: String? = nil
    var assetSymbol: String? = nil
    var assetIcon: String? = nil
    var assetWidth: Int? = nil
    var assetHeight: Int? = nil

    var sharedUserId: String? = nil
    var sharedUserFullName: String = ""
    var sharedUserIdentityNumber: String = ""
    var sharedUserAvatarUrl: String = ""
    var sharedUserAppId: String = ""
    var sharedUserIsVerified: Bool = false

    var quoteMessageId: String? = nil
    var quoteContent: Data? = nil
    
    var userIsBot: Bool {
        return !(appId?.isEmpty ?? true)
    }
    
    lazy var quoteSubtitle: String = {
        if category.hasSuffix("_TEXT") {
            return content
        } else if category.hasSuffix("_STICKER") {
            return Localized.CHAT_QUOTE_TYPE_STICKER
        } else if category.hasSuffix("_IMAGE") {
            return Localized.CHAT_QUOTE_TYPE_PHOTO
        } else if category.hasSuffix("_VIDEO") {
            return Localized.CHAT_QUOTE_TYPE_VIDEO
        } else if category.hasSuffix("_AUDIO") {
            if let duration = mediaDuration {
                return mediaDurationFormatter.string(from: TimeInterval(Double(duration) / millisecondsPerSecond)) ?? ""
            } else {
                return ""
            }
        } else if category.hasSuffix("_DATA") {
            return name ?? ""
        } else if category == MessageCategory.SYSTEM_ACCOUNT_SNAPSHOT.rawValue {
            return (snapshotAmount ?? "0") + " " + (assetSymbol ?? "")
        } else if category.hasSuffix("_CONTACT") {
            return sharedUserIdentityNumber
        } else {
            return ""
        }
    }()

    var isExtensionMessage: Bool {
        return category == MessageCategory.EXT_UNREAD.rawValue || category == MessageCategory.EXT_ENCRYPTION.rawValue
    }

    var isSystemMessage: Bool {
        return category == MessageCategory.SYSTEM_CONVERSATION.rawValue
    }

    init() {
        
    }
}

extension MessageItem {
    
    static func createMessage(toxMessage: OCTMessageAbstract, friendName: String? = nil) -> MessageItem {
        let message = MessageItem()
        message.model = toxMessage
        message.messageId = toxMessage.uniqueIdentifier
        message.isOutgoing = toxMessage.isOutgoing()
        message.userFullName = friendName ?? ""
        
        if let text = toxMessage.messageText {
            message.category = "_TEXT"
            message.status = text.isDelivered ? MessageStatus.READ.rawValue : MessageStatus.SENDING.rawValue
            message.content = text.text ?? ""
        } else if let file = toxMessage.messageFile {
            message.category == "_IMAGE"
            
            switch file.fileType {
            case .waitingConfirmation, .loading:
                message.status = MessageStatus.SENDING.rawValue
                message.mediaStatus = MediaStatus.PENDING.rawValue
            case .canceled, .paused:
                message.status = MessageStatus.FAILED.rawValue
                message.mediaStatus = MediaStatus.EXPIRED.rawValue
            case .ready:
                message.status = MessageStatus.READ.rawValue
                message.mediaStatus = MediaStatus.DONE.rawValue
            }
            
            if let json = file.fileName, let model: DataModel = json.toModel() {
                message.category = model.category
                
                if message.category == "_IMAGE" {
                    
                    message.mediaWidth = Int(model.width)
                    message.mediaHeight = Int(model.height)
                } else if message.category == "_DATA" {
                    message.mediaSize = Int64(model.fileSize)
                } else {
                    print("🤣🤣🤣消息类型不认识🤣🤣🤣")
                }
            } else {
                print("🤣🤣🤣消息类型不认识🤣🤣🤣")
            }
            
            message.mediaUrl = file.filePath()
        }
        
        message.conversationId = toxMessage.chatUniqueIdentifier
        message.createdAt = toxMessage.date().toUTCString()
        return message
    }
}

extension MessageItem {

    static func createMessage(category: String, conversationId: String, createdAt: String) -> MessageItem {
        let message = MessageItem()
        message.messageId = UUID().uuidString.lowercased()
        message.status = MessageStatus.SENDING.rawValue
        message.category = category
        message.conversationId = conversationId
        message.createdAt = createdAt
        return message
    }

}

extension MessageItem {

    func isRepresentativeMessage(conversation: ConversationItem) -> Bool {
        guard conversation.category != ConversationCategory.GROUP.rawValue else {
            return true
        }
        return conversation.ownerId != userId && conversation.category == ConversationCategory.CONTACT.rawValue
    }
}
